package org.hugh.space.dao.impl;

import java.util.List;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;

import org.hugh.space.dao.BaseDao;
import org.hugh.space.entity.BaseEntity;




public class BaseDaoImpl <K,T extends BaseEntity> extends AbstractDaoImpl implements BaseDao<K,T> {
	
	private Class clazz;
	
	public BaseDaoImpl(Class aClass) {
		clazz = aClass;
	}
	
	@Override
	public T save(final T entity) {
		PersistenceManager pm = getPersistenceManager();
		try {
			return pm.makePersistent(entity);
		}
		finally {
			pm.close();
		}
	}
	
	@Override
	public T getById(final K id) {
		if (id == null) {
			return null;
		}
		T entity = null;
		if (entity == null) {
			PersistenceManager pm = getPersistenceManager();
			pm.setDetachAllOnCommit(true);
			try {
				entity = (T)pm.getObjectById(clazz, id);
			}
			catch (JDOObjectNotFoundException e) {
				entity = null;
			}
			catch (IllegalArgumentException e) {
				entity = null;
			}
			finally {
				pm.close();
			}
		}
		return entity;
	}
	
	@Override
	public void remove(final K id) {
		if (id == null) {
			return;
		}
		PersistenceManager pm = getPersistenceManager();
		try {
			pm.deletePersistent(pm.getObjectById(clazz, id));
		}
		finally {
			pm.close();
		}
	}
	
	@Override
	public void remove(final List<K> ids) {
		PersistenceManager pm = getPersistenceManager();
		try {
			for (K id : ids) {
				if (id != null) {
					pm.deletePersistent(pm.getObjectById(clazz, id));
				}
			}
		}
		finally {
			pm.close();
		}
	}

	protected void removeSelected(String query, Object[] params) {
		PersistenceManager pm = getPersistenceManager();
		try {
			List<T> result =  (List<T>) pm.newQuery(query).executeWithArray(
					params);
			pm.deletePersistentAll(result);
		}
		finally {
			pm.close();
		}
	}
	
	protected List<T> select(String query, Object[] params) {
		List<T> result = null;
		if (result == null) {
			PersistenceManager pm = getPersistenceManager();
			pm.setDetachAllOnCommit(true);
			try {
				result =  copy((List<T>) pm.newQuery(query)
						.executeWithArray(params));
			}
			finally {
				pm.close();
			}
		}
		return result;
	}

	@Override
	public List<T> select() {
		List<T> result = null;
		if (result == null) {
			PersistenceManager pm = getPersistenceManager();
			pm.setDetachAllOnCommit(true);
			try {
				result = copy((List<T>)pm.newQuery("select from " + clazz.getName())
						.execute());
			}
			finally {
				pm.close();
			}
		}
		return result;
	}

	protected T selectOne(String query, Object[] params) {
		List<T> list = select(query, params);
		if (list.isEmpty()) {
			return null;
		}
		return list.get(0);
	}
		
	protected Object[] params(Object...objects) {
		return objects;
	}

	@Override
	public void removeAll() {
		removeSelected("select from " + clazz.getName(), params());
	}

}
